package com.butterfly.hotkey.dashboard.biz.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.butterfly.hotkey.core.util.thread.SimpleAsyncUtils;
import com.butterfly.hotkey.dashboard.biz.service.KeyService;
import com.butterfly.hotkey.core.constant.Constants;
import com.butterfly.hotkey.core.model.HotKeyModel;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import static com.butterfly.hotkey.core.constant.NumConst.ONE_HUNDRED;

/**
 * <p>
 * key操作记录表 服务类
 * </p>
 *
 * @author butterfly
 * @since 2024-10-24
 */
@Service
public class KeyServiceImpl implements KeyService {

    private final static Logger log = LoggerFactory.getLogger(Constants.DASHBOARD);

    /**
     * 每次推送多少个hotkey
     */
    private static final int DEFAULT_BATCH_SIZE = ONE_HUNDRED;

    /**
     * QUEUE的超时时间, 1s
     */
    private static final int DEFAULT_QUEUE_TIMEOUT = ONE_HUNDRED;

    /**
     * 热key队列
     */
    private static final LinkedBlockingQueue<HotKeyModel> QUEUE = new LinkedBlockingQueue<>();

    @PostConstruct
    public void init() {
        // TODO
        SimpleAsyncUtils.execute(() -> {
            while (true) {
                saveHotkeysToDb();
            }
        });

    }

    private void saveHotkeysToDb() {
        List<HotKeyModel> waitSaveModels = new ArrayList<>();
        // 当数据达到1000条，或者1s时，都进行推送
        // TODO 推送间隔配置化

        try {
            Queues.drain(QUEUE, waitSaveModels, DEFAULT_BATCH_SIZE, DEFAULT_QUEUE_TIMEOUT, TimeUnit.MILLISECONDS);
            if (CollectionUtil.isEmpty(waitSaveModels)) {
                return;
            }

            List<List<HotKeyModel>> keyParts = Lists.partition(waitSaveModels, DEFAULT_BATCH_SIZE);
            for (List<HotKeyModel> keyPart : keyParts) {
                // TODO 保存产生hotkey
            }

        } catch (Exception e) {
            log.error("push hot key to app failed", e);
        }


    }


    @Override
    public void addHotKeys(Collection<HotKeyModel> hotKeyModels) {
        for (HotKeyModel hotKeyModel : hotKeyModels) {
            QUEUE.offer(hotKeyModel);
        }
    }


}
